package com.bqjr.xms.service.impl;

import com.bqjr.xms.modle.ConsumerBeehiveUser;
import com.bqjr.xms.service.ConsumerBeehiveUserService;
import com.netflix.hystrix.contrib.javanica.annotation.HystrixCommand;
import com.netflix.hystrix.contrib.javanica.annotation.HystrixProperty;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.web.client.RestTemplate;

import java.util.Random;

/**
 * Description: ConsumerBeehiveUserServiceImpl.
 * 这边采取了和Spring Cloud官方文档相同的做法，将fallback类作为内部类放入Feign的接口中，当然也可以单独写一个fallback类。
 *
 * Created by XHZ on 2017/8/6.
 */
@Component
public class ConsumerBeehiveUserServiceImpl implements ConsumerBeehiveUserService {
    private static final Logger logger = LoggerFactory.getLogger(ConsumerBeehiveUserServiceImpl.class);
    private static int sleepRandom;
    @Autowired
    RestTemplate restTemplate;
    /**
     * hystrix fallback方法
     * @param id id
     * @return 默认的用户
     */
    @HystrixCommand(fallbackMethod = "findByIdFallback")
    public ConsumerBeehiveUser findById(Long id) {
        //调用provider-user提供者的方法
        return restTemplate.getForObject("http://provider-user/user/"+id, ConsumerBeehiveUser.class);
    }

    public ConsumerBeehiveUser findByIdFallback(Long id) {
        logger.info("异常发生，进入fallback方法，接收的参数：id = {}", id);
        ConsumerBeehiveUser user = new ConsumerBeehiveUser();
        user.setId(id);
        user.setUsername("consumer-beehive username，this messge send failed");
        user.setAge(0);
        return user;
    }

    @HystrixCommand(fallbackMethod = "findOrderFallback", commandProperties = {
            //timeoutInMilliseconds 使用线程隔离时，调用超时时间
            @HystrixProperty(name = "execution.isolation.thread.timeoutInMilliseconds", value = "1000")
    })
    public String findOrder(Long userId,String orderNo) throws InterruptedException {
        Random random = new Random();
        sleepRandom = random.nextInt(2000);
        System.out.println("sleepRandom="+sleepRandom);
        Thread.sleep(sleepRandom);
        ConsumerBeehiveUser user = findById(userId);
        if (user != null) {
            return user.getUsername() + " 的订单" + orderNo + " 找到啦！sleepRandom="+sleepRandom;
        }
        return "用户不存在！sleepRandom="+sleepRandom;
    }

    public String findOrderFallback(Long userId, String orderNo) {
        return "订单查找失败！sleepRandom="+sleepRandom;
    }

    @HystrixCommand(fallbackMethod = "testCircuitBreakerFallback", commandProperties = {
            //errorThresholdPercentage 断路器错误请求百分比
            @HystrixProperty(name = "circuitBreaker.errorThresholdPercentage", value = "50")
    })
    public String testCircuitBreaker(int id) {
        if(id % 2 == 0 && id < 10) {	// 直接返回
            return "consumer testCircuitBreaker "+id;
        } else {	// 无限循环模拟超时
            int j = 0;
            while (true) {
                j++;
            }
        }
    }

    public String testCircuitBreakerFallback(int id) {
        String template = restTemplate.getForObject("http://provider-user/user/testCircuitBreaker/"+id, String.class);
        return "fallback："+template;
    }

}
